package com.liveims.webims.util;


import java.util.HashMap;

import javax.naming.Binding;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.naming.event.EventContext;
import javax.naming.event.NamingEvent;
import javax.naming.event.NamingExceptionEvent;
import javax.naming.event.ObjectChangeListener;
import org.apache.log4j.Logger;



/**
 * The configuration parameters.
 */
public class Settings {
	
	public static enum Attribute {

		IMS_DOMAIN_PROPERTY		("webims.ims_domain"),
		XDMS_PROPERTY		    ("webims.xdms_ip"),
		S_CSCF_PROPERTY	        ("webims.s-cscf");
		//MUX_REG_TIME		    ("webims.reg_expire");
		

		private String _attributeKey;	
		private Attribute(String attributeKey)
		{
			_attributeKey = attributeKey;
		}
		public String getAttributeKey(){
			return _attributeKey;
		}
	};
	
	// ----- Private Attributes
	private final HashMap<Attribute, String> _attributeTable = new HashMap<Attribute, String>();
	private static final Logger LOGGER = Logger
			.getLogger("com.liveims.webims.Settings");
	private static Settings _instance;
	
	public static Settings getInstance()
	{
		if (_instance == null)
		{
			_instance = new Settings();
		}
		return _instance;
	}
	
	/**
	 * @return the attribute value (in String format) stored in ProxyPlatform ICX settings.
	 */
	public String valueOf(Attribute attribute) {
		return _attributeTable.get(attribute);
	} 
	
	private Settings()
	{ 
	  try{
    	// Retrieves the Proxy Application properties
		InitialContext ctx = new InitialContext();
		// get attribute list
    	Attribute[] attributes = Attribute.values();
    	
    	for(Attribute attribute : attributes){
    		String attributeKey = attribute.getAttributeKey();
    		_attributeTable.put(attribute,  getConfParameter(ctx, attributeKey, ""));		
		
    	   // ---------------------------------------
		   // Add listeners on dynamic properties
		   // ---------------------------------------
		   EventContext eventCtx = (EventContext) ctx.lookup("");
		   eventCtx.addNamingListener(attributeKey,
				EventContext.OBJECT_SCOPE, new PropertyListener(attribute));		
			
			if (LOGGER.isDebugEnabled()) {
				LOGGER.debug("Get configuration properties:"
						+ attributeKey + "=" + getConfParameter(ctx, attributeKey, "")
				);
			}
    	}
	  }catch(NamingException e){
		  if (LOGGER.isDebugEnabled()) {
				LOGGER.error("error when Get configuration properties", e);
		  }
	  }
		
	}

	private static String getConfParameter(InitialContext ctx, String prop,
			String def) {
		try {
			return (String) ctx.lookup(prop);
		} catch (Exception e) {
			LOGGER.error("Could not parse properies " + prop, e);
		}
		return def;
	}

   class PropertyListener implements ObjectChangeListener{
        private Attribute attri;
        public PropertyListener(Attribute a){
        	attri= a;
        }
		public void objectChanged(NamingEvent evt) {
			try {
				Binding newBinding = evt.getNewBinding();
				_attributeTable.put(attri, (String)newBinding.getObject());
				if (LOGGER.isDebugEnabled()) {
					LOGGER
							.debug("new value for ims_domain"
									+ attri.getAttributeKey());
				}
			} catch (Exception e) {
				LOGGER
						.error(
								"Failed to reload "+ attri.getAttributeKey()+ " value",
								e);
			}		
		}		
		public void namingExceptionThrown(NamingExceptionEvent ev) {
			LOGGER
			.error("namingExceptionThrown - while listening to "
					+ attri._attributeKey
					+ ": "
					+ ev);	
		}
   }
}

